package bgai.gui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

import bgai.gamelogic.Backgammon;
import bgai.gamelogic.BackgammonError;
import bgai.gamelogic.CheckerColor;

/**
 * La bar in cui vengono posizionate le pedine mangiate
 */
public class Bar extends JPanel{
	
	private static final long serialVersionUID = -8450246149455282006L;
	
	/**
	 * la parte della bar in cui vengono messe le pedine bianche mangiate
	 */
	private JLayeredPane whiteSpace;
	
	/**
	 * la parte della bar in cui vengono messe le pedine nere mangiate
	 */
	private JLayeredPane blackSpace;
	
	/** 
	 * i pannelli sovrapposti per il JLayeredPane dei checker bianchi
	 */
	private JPanel bottomWhitePanel,halfWhitePanel,upperWhitePanel;
	
	/** 
	 * i pannelli sovrapposti per il JLayeredPane dei checker neri
	 */
	private JPanel bottomBlackPanel, halfBlackPanel,upperBlackPanel;
	
	/**
	 * I checker neri presenti sul bar
	 */
	private ArrayList<Checker> blackCheckers;
	
	
	/**
	 * I checker bianchi presenti sul bar
	 */
	private ArrayList<Checker> whiteCheckers;

	/**
	 * L'istanza BackgammonGUI in cui posizionare la bar
	 */
	private BackgammonGUI bgGUI;
	
	public Bar(BackgammonGUI bgGUI){
		
		super();
		this.bgGUI=bgGUI;
		this.setBackground(new Color(139,69,19));
		float percWidth= ((float) 5/100) * bgGUI.getWidth();
		this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    	this.setPreferredSize(new Dimension((int)percWidth, (int)bgGUI.getHeight()));
    	this.setMinimumSize(new Dimension((int)percWidth, (int)bgGUI.getHeight()));
		
    	
		float emptyHeight= ((float) 10/100) * bgGUI.getHeight();

		// la parte per le pedine nere mangiate
		blackSpace=new JLayeredPane(); 
		blackSpace.setBackground(new Color(139,69,19));
		blackSpace.setBounds(new Rectangle((int) percWidth, (bgGUI.getHeight()-((int)emptyHeight*2))/2));
		//blackSpace.setBorder(BorderFactory.createLineBorder(Color.red));
		System.out.println("barBlackSpace --> "+ blackSpace.getWidth() +", "+blackSpace.getHeight());
		
		// la parte per le pedine bianche mangiate
		whiteSpace=new JLayeredPane();
		whiteSpace.setBackground(new Color(139,69,19));
		whiteSpace.setBounds(new Rectangle((int) percWidth, (bgGUI.getHeight()-((int)emptyHeight*2))/2));
		//whiteSpace.setBorder(BorderFactory.createLineBorder(Color.black));
		System.out.println("barWhiteSpace --> "+ whiteSpace.getWidth() +", "+whiteSpace.getHeight());

		
		
		// il pannello nero che contiene le prime 5 pedine (da 1 a 5)
		bottomBlackPanel = new JPanel();
		bottomBlackPanel.setPreferredSize(new Dimension(blackSpace.getWidth(), blackSpace.getHeight()));
		bottomBlackPanel.setSize(new Dimension(blackSpace.getWidth(), blackSpace.getHeight()));
		bottomBlackPanel.setLayout(new BoxLayout(bottomBlackPanel, BoxLayout.PAGE_AXIS));
		bottomBlackPanel.setOpaque(false);
		
		// il pannello bianco che contiene le prime 5 pedine (da 1 a 5)
		bottomWhitePanel = new JPanel();
		bottomWhitePanel.setPreferredSize(new Dimension(whiteSpace.getWidth(), whiteSpace.getHeight()));
		bottomWhitePanel.setSize(new Dimension(whiteSpace.getWidth(), whiteSpace.getHeight()));
		bottomWhitePanel.setLayout(new BoxLayout(bottomWhitePanel, BoxLayout.PAGE_AXIS));
		bottomWhitePanel.setOpaque(false);
		
		// il pannello nero che contiene le pedine da 6 a 10
		halfBlackPanel = new JPanel();
		halfBlackPanel.setPreferredSize(new Dimension(blackSpace.getWidth(), blackSpace.getHeight()));
		halfBlackPanel.setSize(new Dimension(blackSpace.getWidth(), blackSpace.getHeight()));
		halfBlackPanel.setLayout(new BoxLayout(halfBlackPanel, BoxLayout.PAGE_AXIS));
		halfBlackPanel.setOpaque(false);
		
		// il pannello bianco che contiene le pedine da 6 a 10
		halfWhitePanel = new JPanel();
		halfWhitePanel.setPreferredSize(new Dimension(whiteSpace.getWidth(), whiteSpace.getHeight()));
		halfWhitePanel.setSize(new Dimension(whiteSpace.getWidth(), whiteSpace.getHeight()));
		halfWhitePanel.setLayout(new BoxLayout(halfWhitePanel, BoxLayout.PAGE_AXIS));
		halfWhitePanel.setOpaque(false);
		
		// il pannello nero che contiene le pedine da 11 a 15
		upperBlackPanel = new JPanel();
		upperBlackPanel.setPreferredSize(new Dimension(blackSpace.getWidth(), blackSpace.getHeight()));
		upperBlackPanel.setSize(new Dimension(blackSpace.getWidth(), blackSpace.getHeight()));
		upperBlackPanel.setLayout(new BoxLayout(upperBlackPanel, BoxLayout.PAGE_AXIS));
		upperBlackPanel.setOpaque(false);
		
		// il pannello bianco che contiene le pedine da 11 a 15
		upperWhitePanel = new JPanel();
		upperWhitePanel.setPreferredSize(new Dimension(whiteSpace.getWidth(), whiteSpace.getHeight()));
		upperWhitePanel.setSize(new Dimension(whiteSpace.getWidth(), whiteSpace.getHeight()));
		upperWhitePanel.setLayout(new BoxLayout(upperWhitePanel, BoxLayout.PAGE_AXIS));
		upperWhitePanel.setOpaque(false);
		
		
		blackSpace.add(bottomBlackPanel,new Integer(1));
		whiteSpace.add(bottomWhitePanel,new Integer(1));
				
		this.add(Box.createRigidArea(new Dimension(0,(int)emptyHeight-22)));
		this.add(blackSpace);
		this.add(whiteSpace);
		this.add(Box.createRigidArea(new Dimension(0,(int)emptyHeight-22)));
		
		blackCheckers= new ArrayList<Checker>();
		whiteCheckers= new ArrayList<Checker>();

		
	}
	
	
	/**
	 * Ottiene il numero di checkers di un player sulla bar
	 * @param col il colore del player al quale si sta facendo riferimento
	 * @return il numero dei checkers del player 'col' sulla bar o -1 se c'e' stato un errore nel passaggio del colore
	 */
	public int getNumBarCheckers(CheckerColor col){
		
		if(col==CheckerColor.BLACK){
			
			return blackCheckers.size();
		}
		
		else if(col==CheckerColor.WHITE){
			
			return whiteCheckers.size();
		}
		
		
		else return -1;
		
		
	}
	
	/**
	 * Aggiunge un checker che e' stato mangiato alla bar
	 * @param col il colore del checker da aggiungere
	 */
	public void addChecker(CheckerColor col){
			
		Checker c= new Checker(col,Backgammon.BAR);
		
		ImageIcon img= c.setScaledImage((int)(-1),(int)(whiteSpace.getHeight()/6)); // uso whiteSpace perche' sia blackspace che whitespace hanno la stessa dimensione
				
		int numCheckers;
				
		// il numero di checker sul bar e' stato gia' aggiornato da Backgammon
		//int numCheckers = bgGUI.getBg().getBarCheckers(col);
				
		JPanel panel=null;
		int i = -1;
		
		if(col==CheckerColor.BLACK){ // e' stata mangiata una pedina nera
			
			numCheckers=blackCheckers.size()+1;
			
			if(numCheckers<=5){ // se ==5 significa che ero a 4 checker devo mettere il quinto
				
				panel=bottomBlackPanel;
				i=5;

			}
			
			else if(numCheckers<=10){ // point che contiene da 6 checker a 10 checker
				
				if(numCheckers==6){ // e' il primo checker che devo mettere sovrapposto nel pannello in mezzo
					blackSpace.add(halfBlackPanel, new Integer(2));
					halfBlackPanel.add(Box.createRigidArea(new Dimension(img.getIconWidth(),img.getIconHeight()/2)));
					blackSpace.revalidate();
					blackSpace.repaint();
				}
				
				panel=halfBlackPanel;
				i=10;
				
			}
			
			else if(numCheckers<=15){ // point che contiene da 11 a 15 checker
		
				if(numCheckers==11){ // e' il primo checker che devo mettere sovrapposto nel pannello superiore
					blackSpace.add(upperBlackPanel, new Integer(3));
					blackSpace.revalidate();
					blackSpace.repaint();
				}			
				panel=upperBlackPanel;
				i=15;
			}
			
			else{ //non ci possono essere piu' di 15 checker nel point
				
				throw new BackgammonError(bgGUI.getBg(), "Il numero delle pedine nel nere mangiate non puo' essere > 15");
				
			}
			
			// salvo il nuovo checker inserito
			blackCheckers.add(c);
			
		}
		
		else{ // e' stata mangiata una pedina bianca
			
			numCheckers=whiteCheckers.size()+1;
			
			if(numCheckers<=5){ // se ==5 significa che ero a 4 checker devo mettere il quinto
				
				panel=bottomWhitePanel;
				i=5;

			}
			
			else if(numCheckers<=10){ // point che contiene da 6 checker a 10 checker
				
				if(numCheckers==6){ // e' il primo checker che devo mettere sovrapposto nel pannello in mezzo
					whiteSpace.add(halfWhitePanel, new Integer(2));
					whiteSpace.revalidate();
					whiteSpace.repaint();
				}
				
				panel=halfWhitePanel;
				i=10;
				
			}
			
			else if(numCheckers<=15){ // point che contiene da 11 a 15 checker
		
				if(numCheckers==11){ // e' il primo checker che devo mettere sovrapposto nel pannello superiore
					whiteSpace.add(upperWhitePanel, new Integer(3));
					whiteSpace.revalidate();
					whiteSpace.repaint();
				}			
				panel=upperWhitePanel;
				i=15;
			}
			
			else{ //non ci possono essere piu' di 15 checker nel point
				
				throw new BackgammonError(bgGUI.getBg(), "Il numero delle pedine bianche mangiate non puo' essere > 15");
				
			}
			
			// salvo il nuovo checker inserito
			whiteCheckers.add(c);
			
		}
		

		
		if(col==CheckerColor.WHITE){ // mangiata pedina bianca
			
			panel.removeAll();
			
			// posizionare le pedine nella parte bassa dei points numerati da 1 a 12
			for(;i>=(whiteCheckers.size());i--){
				
				if(panel==halfWhitePanel && i==10){ //panel==halfPanel
					
					panel.add(Box.createRigidArea(new Dimension(img.getIconWidth(),img.getIconHeight()/2)));
					
				}
				else{
					
					panel.add(Box.createRigidArea(new Dimension(img.getIconWidth(),img.getIconHeight())));
				}
			}
				
			int k=-1;
			if(panel==bottomWhitePanel){
				
				k=0;
				
			}
			else if(panel==halfWhitePanel){
				
				k=5;
			}
			else{ //upperWhitePanel
				
				k=10;
			}
			for(int j=(whiteCheckers.size()-1);j>=k;j--){
				panel.add(whiteCheckers.get(j));
			}
			
		}
		else{ //mangiata pedina nera
			// aggiungo graficamente il checker alla bar
			panel.add(c);
		}

		panel.revalidate();
		panel.repaint();
		
	}
	
	/**
	 * Rimuove un checker del colore col dalla bar
	 * @param col il colore del checker da rimuovere dalla bar
	 */
	public void removeChecker(CheckerColor col){
		
		
		// il numero di checker sul bar e' stato gia' aggiornato da Backgammon
		int numCheckers = bgGUI.getBg().getBarCheckers(col);
				
		JPanel panel=null;

		int i = -1;
		
		if(col==CheckerColor.BLACK){ // una pedina nera e' rientrata in gioco
			
			if(numCheckers<=5){ // devo rimuovere un checker dal bottomPanel
				
				panel=bottomBlackPanel;
				i=5;
			}
			
			else if(numCheckers<=10){ //devo rimuovere un checker dall'halfPanel
				
				i=10;
		
				panel=halfBlackPanel;				
	
			}
			
			else if(numCheckers<=15){ //devo rimuovere un checker dall'upperPanel
				
				panel=upperBlackPanel;
				
				i=15;
			}
			
			else{ //non ci possono essere piu' di 15 checker nel point
				
				throw new BackgammonError(bgGUI.getBg(), "Il numero delle pedine nere nel bar non puo' essere > 15");
				
			}
			
		}
		
		else{ // una pedina bianca e' rientrata in gioco
						
			if(numCheckers<=5){ // devo rimuovere un checker dal bottomPanel
				
				panel=bottomWhitePanel;
				i=5;
			}
			
			else if(numCheckers<=10){ //devo rimuovere un checker dall'halfPanel
				
				i=10;
		
				panel=halfWhitePanel;				
	
			}
			
			else if(numCheckers<=15){ //devo rimuovere un checker dall'upperPanel
				
				panel=upperWhitePanel;
				
				i=15;
			}
			
			else{ //non ci possono essere piu' di 15 checker nel point
				
				throw new BackgammonError(bgGUI.getBg(), "Il numero delle pedine bianche nel bar non puo' essere > 15");
				
			}

		}
	
			
		
		if(col==CheckerColor.WHITE){ // il cheker da rimuovere e' bianco
			
			whiteCheckers.remove(whiteCheckers.size() - 1);
			
			panel.removeAll();
			
			ImageIcon img=(new Checker(CheckerColor.WHITE)).setScaledImage((int)(-1),(int)(whiteSpace.getHeight()/6)); //checker usato solo per ottenere larghezza ed altezza img

			
			// posizionare le pedine nella parte bassa dei points numerati da 1 a 12
			for(;i>=(whiteCheckers.size());i--){
				
				if(panel==halfWhitePanel && i==10){ //panel==halfWhitePanel
					
					panel.add(Box.createRigidArea(new Dimension(img.getIconWidth(),img.getIconHeight()/2)));
				}
				else{
					panel.add(Box.createRigidArea(new Dimension(img.getIconWidth(),img.getIconHeight())));
				}
			}
			
			int k=-1;
			if(panel==bottomWhitePanel){
				
				k=0;
				
			}
			else if(panel==halfWhitePanel){
				
				k=5;
			}
			else{ //upperPanel
				
				k=10;
			}
			
			for(int j=(whiteCheckers.size()-1);j>=k;j--){
				panel.add(whiteCheckers.get(j));
			}
			
			panel.revalidate();
			panel.repaint();
			
		}
		else{ //il checker da rimuovere e' nero
			
			//rimuovo l'ultimo checker inserito dal pannello...
			panel.remove(blackCheckers.get(blackCheckers.size() - 1));
			//...e dall'array di checker
			blackCheckers.remove(blackCheckers.size() - 1);
			panel.revalidate();
			panel.repaint();
		}
		
		if(numCheckers==0 || numCheckers==5 || numCheckers==10){ //ho rimosso l'unico checker presente in bottomPanel, halfPanel o in upperPanel (devo rimuovere halfPanel o upperPanel)
			// rimuovo tutti gli eventuali spazi aggiunti ad halfPanel
			panel.removeAll();
			panel.revalidate();
			panel.repaint();
			
			if(col==CheckerColor.BLACK && numCheckers!=0){ //non devo rimuovere bottomPanel
				
				blackSpace.remove(panel);
				blackSpace.revalidate();
				blackSpace.repaint();
				
			}
			
			else if(col==CheckerColor.WHITE && numCheckers!=0){ //non devo rimuovere bottomPanel
				
				whiteSpace.remove(panel);
				whiteSpace.revalidate();
				whiteSpace.repaint();
				
			}
			
		}
		
	}
	
	/**
	 * Evidenzia l'ultimo checker aggiunto sul bar appartenente al player di colore col
	 * @param col il colore del gruppo di checker sul quale agire
	 */
	public void highlightChecker(CheckerColor col){
		
		Checker c;
		
		if(col==CheckerColor.BLACK){
			
			c=blackCheckers.get(blackCheckers.size()-1);
		}
		else{
			
			c=whiteCheckers.get(whiteCheckers.size()-1);

		}
		
		if(!c.isHighlighted()){
			
			// cambio l'immagine della label in quella evidenziata
			c.setHighlightedImage((int)(-1),(int)(blackSpace.getHeight()/6)); // uso blackSpace perche' sia blackspace che whitespace hanno la stessa dimensione
		
			Cursor handCurs = new Cursor(Cursor.HAND_CURSOR);
			c.setCursor(handCurs);
				
			// aggiungo il listener per il click sul checker
			c.addMouseListener(bgGUI);
		}
		
	}
	
	/**
	 * Rimuovi evidenziazione dell'ultimo checker aggiunto al bar appartenente al player di colore col
	 * @param col il colore del gruppo di checker sul quale agire
	 */
	public void disableHighlight(CheckerColor col){
		
		
Checker c;
		
		if(col==CheckerColor.BLACK){
			
			c=blackCheckers.get(blackCheckers.size()-1);
		}
		else{
			
			c=whiteCheckers.get(whiteCheckers.size()-1);

		}
		
		if(c.isHighlighted()){
			
			// cambio l'immagine della label in quella evidenziata
			c.setScaledImage((int)(-1),(int)(blackSpace.getHeight()/6)); // uso blackSpace perche' sia blackspace che whitespace hanno la stessa dimensione
			c.setCursor(null);				
			// aggiungo il listener per il click sul checker
			c.removeMouseListener(bgGUI);
		}
		
	}
	

}
